package com.xtinno.service.impl;

import cn.hutool.http.HttpRequest;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import com.xtinno.common.MDCUtils;
import com.xtinno.config.ConfigCenter;
import com.xtinno.dal.dto.WorkflowDefinitionModel;
import com.xtinno.dal.service.IWorkflowDefinitionService;
import com.xtinno.dal.service.IWorkflowService;
import com.xtinno.dal.service.impl.WorkflowBaseServiceImpl;
import com.xtinno.models.CasecauseLabelModel;
import com.xtinno.models.WorkFlowRequestModel;
import com.xtinno.service.WorkFowService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.MDC;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.stream.Collectors;

/**
 * 案由特征工作流实现
 */
@Slf4j
@Service("CauseTraitWorkFlowImpl")
@Scope("prototype")
public class CauseTraitWorkFlowImpl extends WorkFlowServiceImpl implements WorkFowService {

    public CauseTraitWorkFlowImpl(WorkflowBaseServiceImpl workflowBaseService, IWorkflowService workflowService, IWorkflowDefinitionService workflowDefinitionService, ConfigCenter configCenter) {
        super(workflowBaseService, workflowService, workflowDefinitionService, configCenter);
    }

    /**
     * 获取案由标签
     *
     * @param causeID
     * @return
     */
    @Cacheable(value = "myCacheCauseLabel", key = "#causeID")
    public List<CasecauseLabelModel> getCauseLabel(String causeID) {
        var url = configCenter.getSystemAPI() + "/system/v1/casecauselabel/" + causeID;
        String result = HttpRequest.get(url)
                .timeout(100000)//超时，毫秒
                .execute().body();
        log.info("工作流执行-获取案由标签", result);
        JSONObject obj = JSON.parseObject(result);
        JSONArray body = (JSONArray) obj.get("Body");

        List<CasecauseLabelModel> list = JSONArray.parseArray(body.toJSONString(), CasecauseLabelModel.class);
        return list;
    }

    /**
     * 步数执行
     *
     * @param workFlowRequestModel 请求参数
     * @param defaultParam         默认请求模型参数
     * @param gloabMap             全局变量
     * @return
     */
    @Override
    protected String StepRun(WorkFlowRequestModel workFlowRequestModel, JSONObject defaultParam, Map<String, Object> gloabMap) {
        List<Callable<List<JSONObject>>> tasks = new ArrayList<>();
        List<JSONObject> results = new ArrayList<>();
        var labels = getCauseLabel(gloabMap.get("start_causecode").toString());

        Map<String, List<CasecauseLabelModel>> firstGroupLabelVal = new HashMap<>();
        labels.forEach(p -> {
            var excludeLabels=((JSONArray)gloabMap.get("start_labele")).toArray(new String[0]);
            if (!Arrays.stream(excludeLabels).anyMatch(p.getCAllName()::startsWith)) {
                var key = p.getCAllName().split(",");
                p.setCAllName(p.getCAllName().replaceFirst(",", "下的"));
                p.setCAllName(p.getCAllName().replaceFirst(",", "-"));
                if (firstGroupLabelVal.containsKey(key[0])) {
                    firstGroupLabelVal.get(key[0]).add(p);
                } else {
                    var aa = new ArrayList<CasecauseLabelModel>();
                    aa.add(p);
                    firstGroupLabelVal.put(key[0], aa);
                }
            }
        });
        var workflowDetail = workflowDefinitionService.lambdaQuery().eq(WorkflowDefinitionModel::getCWfWorkflowId, workFlowRequestModel.getWorkflowId()).list();
        var llmA01 = workflowDetail.stream().filter(p -> p.getCWfdStepId().equals("a01")).findFirst().get();
        var llmA011 = workflowDetail.stream().filter(p -> p.getCWfdStepId().equals("b01")).findFirst().get();
        firstGroupLabelVal.forEach((key, valueList) -> {
            StringBuilder sb = new StringBuilder();
            valueList.sort(Comparator.comparing(CasecauseLabelModel::getCLabelName));
            valueList.forEach(p -> {
                sb.append(p.getCAllName());
                sb.append("\n");
            });
            // 获取当前线程的MDC上下文信息
            Map<String, String> context = MDC.getCopyOfContextMap();
            Callable<List<JSONObject>> task1 = () -> {
                MDC.setContextMap(context);
                MDC.put("spanId",MDC.get("spanId")+"_"+Thread.currentThread().threadId()+System.currentTimeMillis());
                try {
                    var temp1 = JSONObject.parseObject(JSONObject.toJSONString(llmA01), WorkflowDefinitionModel.class);
                    temp1.setCWfdLlmPromptTemplateSystem(llmA01.getCWfdLlmPromptTemplateSystem().replace("{{causelabel}}", sb.toString()));
                    var firstResult = RunWorkStep(temp1, defaultParam, gloabMap, workflowDetail);
                    List<JSONObject> jsonResults = ValidAndMergeCauseLabel(firstResult, valueList, llmA011, defaultParam, gloabMap, workflowDetail);
                    return jsonResults;
                }catch (Exception exception){
                    log.error("错误信息:{}\r\n异常:{}", exception.getMessage(),exception.getStackTrace());
                    return null;
                }
            };
            tasks.add(task1);
        });

        // 创建线程池
        ExecutorService service = Executors.newVirtualThreadPerTaskExecutor();
        try {
            // 调用invokeAll方法，批量提交一组任务
            List<Future<List<JSONObject>>> futures = service.invokeAll(tasks);
            for (Future<List<JSONObject>> future : futures) {
                // 在这里获取任务的返回值时，会等待所有任务都执行完才返回结果
                List<JSONObject> result = future.get();
                if (result!=null && result.size()>0) {
                    results.addAll(result);
                }
            }
        } catch (Exception exception) {
            log.error("错误信息:{}\r\n异常:{}", exception.getMessage(),exception.getStackTrace());
        } finally {
            // 关闭线程池
            service.shutdown();
            JSONObject rrr1 = new JSONObject();
            rrr1.put("causelable", results);
            return JSONObject.toJSONString(rrr1);
        }
    }

    /**
     * 验证判断并且合并结果
     *
     * @param causeLabelResult
     * @param labels
     * @param llmA011
     * @param defaultParam
     * @param gloabMap
     * @param workflowDetail
     * @return
     */

    private List<JSONObject> ValidAndMergeCauseLabel(String causeLabelResult, List<CasecauseLabelModel> labels, WorkflowDefinitionModel llmA011, JSONObject defaultParam, Map<String, Object> gloabMap, List<WorkflowDefinitionModel> workflowDetail) {
        List<Callable<JSONObject>> tasks = new ArrayList<>();
        var resultArrays = JSONArray.parseArray(causeLabelResult);
        resultArrays.forEach(a -> {
            JSONObject jsonObject = (JSONObject) JSON.toJSON(a);
            if (jsonObject.containsKey("段落中与特征词相关的表述") && jsonObject.containsKey("特征词") && StringUtils.isNotEmpty(jsonObject.get("段落中与特征词相关的表述").toString())) {
                var label = ((String) jsonObject.get("特征词")).split("下的");
                var tempLastLabel = label[label.length - 1].split("-");
                var lastLabel=tempLastLabel[tempLastLabel.length-1];
                //判断是否存在对应的标签说明
                var explainLabel = labels.stream().filter(p -> lastLabel.equals(p.getCLabelName())).findFirst().orElse(null);
                if (explainLabel != null) {
                    // 获取当前线程的MDC上下文信息
                    Map<String, String> context = MDC.getCopyOfContextMap();
                    Callable<JSONObject> task1 = () -> {
                        MDC.setContextMap(context);
                        MDC.put("spanId",MDC.get("spanId")+"_"+Thread.currentThread().threadId()+System.currentTimeMillis());
                        try {
                            var temp1 = JSONObject.parseObject(JSONObject.toJSONString(llmA011), WorkflowDefinitionModel.class);
                            var strTemp=llmA011.getCWfdLlmPromptTemplateUser().replace("{{特征词}}", explainLabel.getCAllName());
                            temp1.setCWfdLlmPromptTemplateUser(strTemp.replace("{{特征词说明}}",explainLabel.getCRemark()));
                            var firstResult = RunWorkStep(temp1, defaultParam, gloabMap, workflowDetail);
                            JSONObject rr1 = new JSONObject();
                            if (firstResult.contains("是")) {
                                rr1.put("labelTag", lastLabel);//段落中与特征词相关的表述
                                rr1.put("cid", explainLabel.getCId());//段落中与特征词相关的表述
                                rr1.put("sourceContent", jsonObject.get("段落中与特征词相关的表述"));
                                return rr1;
                            }
                        }catch (Exception exception){
                            log.error("错误信息:{}\r\n异常:{}", exception.getMessage(),exception.getStackTrace());
                        }
                        return null;
                    };
                    tasks.add(task1);
                }
            }
        });
        List<JSONObject> finalResults = new ArrayList<>();
        // 创建线程池
        ExecutorService service = Executors.newVirtualThreadPerTaskExecutor();
        try {
            // 调用invokeAll方法，批量提交一组任务
            List<Future<JSONObject>> futures = service.invokeAll(tasks);
            for (Future<JSONObject> future : futures) {
                // 在这里获取任务的返回值时，会等待所有任务都执行完才返回结果
                JSONObject result = future.get();
                if (result!=null){
                    finalResults.add(result);
                }
                //var r1 = JSONObject.parseObject(JSONObject.toJSONString(result));
            }
        } catch (Exception exception) {
            log.error("错误信息:{}\r\n异常:{}", exception.getMessage(),exception.getStackTrace());
        } finally {
            // 关闭线程池
            service.shutdown();
            return finalResults;
        }
    }
}
